package org.darkforest.common.services.impl;

import org.darkforest.common.services.SimpleRedisService;
import org.darkforest.common.util.DateUtil;
import org.darkforest.dao.redis.templete.AbstractBaseRedisDao;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.connection.RedisConnection;
import org.springframework.data.redis.core.RedisCallback;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

/**
 * Created by valentina on 15/6/20.
 */
@Component
public class SimpleRedisServiceImpl extends AbstractBaseRedisDao<String,String> implements SimpleRedisService{

    /**
     * 赋值，存在同名key对象时覆盖值
     * @param key
     * @param value
     */
    @Override
    public void setValue(final String key, final String value) {
        try {
            redisTemplate.execute(new RedisCallback<Boolean>() {
                public Boolean doInRedis(RedisConnection connection)
                        throws DataAccessException {
                    RedisSerializer<String> serializer = getRedisSerializer();
                    byte[] k  = serializer.serialize(key);
                    byte[] v = serializer.serialize(value);
                    connection.set(k, v);
                    return true;
                }
            });
        }catch (Exception e){
            e.printStackTrace();
        }

    }

    @Override
    public void setValueInTime(final String key, final String value, final Long second) {
        redisTemplate.execute(new RedisCallback<Boolean>() {
            public Boolean doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] k  = serializer.serialize(key);
                byte[] v = serializer.serialize(value);
                connection.setEx(k, second, v);
                return true;
            }
        });
    }

    @Override
    public boolean setValueNotExist(final String key, final String value) {
        boolean result = redisTemplate.execute(new RedisCallback<Boolean>() {
            public Boolean doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] k  = serializer.serialize(key);
                byte[] v = serializer.serialize(value);
                return connection.setNX(k, v);
            }
        });
        return result;
    }

    @Override
    public String getByKey(final String key) {
        String result = redisTemplate.execute(new RedisCallback<String>() {
            public String doInRedis(RedisConnection connection)
                    throws DataAccessException {
                RedisSerializer<String> serializer = getRedisSerializer();
                byte[] k = serializer.serialize(key);
                byte[] v = connection.get(k);
                if (v == null) {
                    return null;
                }
                String value = serializer.deserialize(v);
                return value;
            }
        });
        return result;
    }

    @Override
    public void deleteByKey(final String key) {
        redisTemplate.execute(new RedisCallback<Object>() {
            public Object doInRedis(RedisConnection connection) {
                connection.del(redisTemplate.getStringSerializer().serialize(key));
                return null;
            }
        });
    }

    @Override
    public Long getValidTime(String key) {

        return redisTemplate.getExpire(key);
    }

    @Override
    public String getExpireTime(String key) {
        Long validTime = this.getValidTime(key);
        return DateUtil.getTimeNearByNow(validTime);
    }


    @Override
    public boolean expire(final String key, long expire) {
        return redisTemplate.expire(key, expire, TimeUnit.SECONDS);
    }
}
